#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <memory>
#include "Thread.hpp"

using namespace std;

uint16_t serverport = 0;
string serverip;

static void usage(string proc)
{
    cout << "usage:" << proc << "serverip serverport" << endl;
}
static void* UdpSend(void* args)
{
    int sock=*(int*)((ThreadData*)args)->_args;
    string name=((ThreadData*)args)->_name;
    string message;
    struct sockaddr_in server;
    bzero(&server,sizeof(server));
    server.sin_family=AF_INET;
    server.sin_port=htons(serverport);
    server.sin_addr=inet_ntoa(serverip.c_str());
    while(true)
    {
        cerr<<"请输入您要发送的信息"<<endl;
        getline(cin,message);
        sendto(sock,message.c_str(),sizeof(message),0,(struct sockaddr*)&server,sizeof(server));
    }
    return nullptr;
}
static void* UdpRecv(void* args)
{
    int sock=*(int*)((ThreadData*)args)->_args;
    char buffer[1024];
    while(true)
    {
        memset(buffer,0,sizeof(buffer));
        struct sockaddr_in temp;
        socklen_t len=sizeof(temp);
        ssize_t s=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,&len);
        if(s > 0)
        {
            buffer[s]=0;
            cout<<buffer<<endl;
        }
    }
}
// static void *UdpSend(void *args)
// {
//     int sock = *(int *)((ThreadData *)args)->_args;
//     string name = ((ThreadData *)args)->_name;
//     char message[1024];
//     struct sockaddr_in server;
//     socklen_t len = sizeof(server);
//     server.sin_family = AF_INET;
//     server.sin_port = ntohs(serverport);
//     server.sin_addr.s_addr = inet_aton(serverip.c_str());
//     while (true)
//     {
//         cerr<<"请输入您的信息"<<endl;
//         getline(cin,message);
//         if(message=="quit")
//         {
//             break;
//         }
//         sendto(sock,message.c_str(),sizeof(message),0,(struct sockaddr*)&server,len);
//     }
//     return nullptr;
// }
// uint16_t serverport=0;
// string serverip;

// static void usage(string proc)
// {
//     cout<<"\nusage:"<<proc<<"serverIp sreverPort\n"<<endl;
// }
// static void* udpSend(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     struct sockaddr_in server;
//     server.sin_addr.s_addr=inet_aton(serverip.c_str());
//     server.sin_family=AF_INET;
//     server.sin_port=htons(serverport);
//     while(true)
//     {
//         cerr<<"请输入您的信息"<<endl;
//         getline(cin,message);
//         if(message=="quit")
//         {
//             break;
//         }
//         sendto(message,sizeof(message),0,(struct sockaddr*)&server,sizeof(server));
//     }
// }
// static void* udpSend(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     char message;
//     //这个结构体地址的作用就是为了接受来自于服务器的套接字
//     struct sockaddr_in server;
//     memset(server,0,sizeof(server));
//     server.sin_addr.s_addr=inet_aton(serverip.c_str());
//     server.sin_port=ntohs(serverport);
//     server.sin_family=AF_INET;
//     while(true)
//     {
//         cerr<<"请输入您的信息"<<endl;
//         getline(cin,message);
//         if(message=="quit")
//         {
//             break;
//         }
//         sendto(message,sizeof(message),0,(struct sockaddr*)&server,sizeof(server));
//     }
// }
// static void* udpSend(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     string message;
//     struct sockaddr_in server;
//     memset(server,0,sizeof(server));
//     //这里要接受一下来自于服务器的套接字地址
//     server.sin_addr.s_addr=inet_aton(serverip.c_str());
//     server.sin_family=AF_INET;
//     server.sin_port=ntohs(serverport);

//     while(true)
//     {
//         cerr<<"请输入您的信息"<<endl;
//         getline(cin,message);
//         if(message=="quit")
//         {
//             break;
//         }
//         sendto(sock,message,sizeof(message),0,(struct sockaddr*)&server,sizeof(server));
//     }
// }
// static void* UdpSend(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     string message;
//     struct sockaddr_in server;
//     memset(&server,0,sizeof(server));
//     server.sin_family=AF_INET;
//     server.sin_port=htons(serverport);
//     server.sin_addr.s_addr=inet_addr(serverip.c_str());
//     while(true)
//     {
//         cerr<<"请输入您的信息"<<endl;
//         getline(cin,message);
//         if(message=="quit")
//         {
//             break;
//         }
//         sendto(sock,message.c_str(),sizeof(message),0,(struct sockaddr*)&message,sizeof(message));
//     }
//     return nullptr;
// }
// //服务器这里需要发送消息
// static void* UdpSend(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     string message;
//     struct sockaddr_in server;
//     memset(server,0,sizeof(server));
//     server.sin_family=AF_INET;
//     server.sin_port=htons(serverport);
//     server.sin_addr.s_addr=inet_addr(serverip.c_str());
//     while(true)
//     {
//         cerr<<"请输入您的信息"<<endl;
//         getline(cin,message);
//         if(message==quit)
//         {
//             break;
//         }
//         sendto(sock,message,sizeof(message),0,(struct sockaddr*)&server,sizeof(server));
//     }
// }
// static void* UdpSend(void* args)
// {
//     //收到了服务器的套接字以后给服务器收发数据
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     string message;
//     struct sockaddr_in server;
//     memset(&server,0,sizeof(server));
//     server.sin_family=AF_INET;
//     server.sin_port=htons(serverport);
//     server.sin_addr.s_addr=inet_addr(serverip.c_str());

//     while(true)
//     {
//         cerr<<"请输入您的信息"<<endl;
//         getline(cin,message);
//         if(message=="quit")
//         {
//             break;
//         }
//         sendto(sock,message.c_str(),sizeof(message),0,(struct sockaddr*)&server,sizeof(server));
//     }
//     return nullptr;
// }
// static void* UdpRecv(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     char buffer[1024];
//     while(true)
//     {
//         struct sockaddr_in temp;
//         socklen_t len=sizeof(temp);
//         memset(temp,0,sizeof(temp));
//         socklen_t len=sizeof(temp);
//         ssize_t s=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,len);
//         if(s > 0)
//         {
//             buffer[s]=0;
//             cout<<buffer<<endl;
//         }
//     }
// }
// static void* UdpRecv(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     char buffer[1024];
//     while(true)
//     {
//         struct sockaddr_in temp;
//         socklen_t len=sizeof(temp);
//         bzero(&temp,sizeof(temp));
//         ssize_t s=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,sizeof(temp));
//         if(s > 0)
//         {
//             buffer[s]=0;
//             cout<<buffer<<endl;
//         }
//     }
// }
// static void* UdpRecv(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     char buffer[1024];
//     while(true)
//     {
//         struct sockaddr_in temp;
//         socklen_t len=sizeof(temp);
//         memset(temp,0,sizeof(temp));
//         socklen_t len=sizeof(temp);
//         ssize_t s=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,len);
//         if(s > 0)
//         {
//             buffer[s]=0;
//             cout<<buffer<<endl;
//         }
//     }
// }
// static void* UdpRecv(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     char buffer[1024];
//     while(true)
//     {
//         struct sockaddr_in temp;
//         socklen_t len=sizeof(temp);
//         memset(temp,0,sizeof(temp));
//         socklen_t len=sizeof(temp);
//         ssize_t s=recvfrom(sock,buffer,sizeof(buffer),(struct sockaddr*)&temp,*len);
//         if(s > 0)
//         {
//             buffer[s]=0;
//             cout<<buffer<<endl;
//         }
//     }
// }
// static void* UdpRecv(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     char buffer[1024];
//     while(true)
//     {
//         memset(buffer,0,sizeof(buffer));
//         struct sockaddr_in temp;
//         socklen_t len=sizeof(temp);
//         ssize_t s=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,&len);
//         if(s > 0)
//         {
//             buffer[s]=0;
//             cout<<buffer<<endl;
//         }
//     }
// }
// static void* UdpRecv(void* args)
// {
//     int sock=*(int*)((ThreadData*)args)->_args;
//     string name=((ThreadData*)args)->_name;
//     char buffer[1024];
//     while(true)
//     {
//         memset(buffer,0,sizeof(buffer));
//         struct sockaddr_in temp;
//         socklen_t len=sizeof(temp);
//         ssize_t s =recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,&len);
//         if(s > 0)
//         {
//             buffer[s]=0;
//             cout<<buffer<<endl;
//         }
//     }
// }

// int main(int argc,char* argv[])
// {
//     if(argc!=3)
//     {
//         usage(argv[0]);
//         exit(1);
//     }
//     //再创建了一个套接字以后就可以进行文件的读写了
//     int sock=socket(AF_INET,SOCK_DGRAM,0);
//     if(sock < 0)
//     {
//         cerr<<"socket error"<<endl;
//         exit(2);
//     }
//     serverport=atoi(argv[i]);
//     serverip=argv[1];

//     unique_ptr<Thread> sender(new Thread(1,udpSend,(void*)&sock));
//     unique_ptr<Thread> recver(new Thread(2,UdpRecv,(void*)&sock));

//     sender->start();
//     recver->start();
//     sender->join();
//     recver->join();
//     close(sock);
//     return 0;
// }